package jmine.tec.services.api.execution;

import bancosys.tec.persist.controller.TransactionalController;

/**
 * Enum de políticas de uso de transações dentro do executor de serviços.
 * 
 * @author lundberg
 */
public enum ExecutorTransactionPolicy {
    /**
     * Política em que o executor cria uma transação por página, mais transações exclusivas para serviços transacionais
     */
    PER_PAGE(true, false, true),
    /**
     * Política em que o executor cria uma, e apenas uma, transação por página, independente dos serviços contidos.
     */
    PER_PAGE_STRICT(true, false, false),
    /**
     * Política em que o executor executa cada serviço em uma transação exclusiva
     */
    PER_SERVICE(false, true, false),
    /**
     * Política em que o executor cria o mínimo de transações, sendo criadas transações extras apenas quando ocorrem serviços transacionais.
     */
    WHEN_NEEDED(false, false, true),
    /**
     * Política em que o executor nunca cria transações.
     */
    NONE(false, false, false) {
        /**
         * Não inicia transação
         * 
         * @param controller um {@link TransactionalController}
         */
        @Override
        public void startTransaction(TransactionalController controller) {
            // faz nada
        }

        /**
         * Não há transação para ser fechada
         * 
         * @param controller um {@link TransactionalController}
         */
        @Override
        public void commitTransaction(TransactionalController controller) {
            // faz nada
        }

        /**
         * Não há transação para dar rollback
         * 
         * @param controller um {@link TransactionalController}
         */
        @Override
        public void rollbackTransaction(TransactionalController controller) {
            // faz nada
        }
    };

    private final boolean perPage;

    private final boolean perService;

    private final boolean whenNeeded;

    /**
     * @param perPage perPage
     * @param perService perService
     * @param whenNeeded whenNeeded
     */
    private ExecutorTransactionPolicy(boolean perPage, boolean perService, boolean whenNeeded) {
        this.perPage = perPage;
        this.perService = perService;
        this.whenNeeded = whenNeeded;
    }

    /**
     * Caso seja verdadeiro, o executor deve iniciar transações no início de cada página e fechar no fim de cada uma. Note que isso não
     * impede que no meio da página exista um serviço que exige uma transação e whenNeeded seja true, nesse caso uma página pode ter mais de
     * 1 transação.
     * 
     * @return the perPage
     */
    public boolean isPerPage() {
        return this.perPage;
    }

    /**
     * Caso seja verdadeiro, cada serviço deve ser executado dentro de uma transação exclusiva.
     * 
     * @return the perService
     */
    public boolean isPerService() {
        return this.perService;
    }

    /**
     * Caso seja verdadeiro, serão criadas transações na medida do necessário para serviços que exigem novas transações.
     * 
     * @return the whenNeeded
     */
    public boolean isWhenNeeded() {
        return this.whenNeeded;
    }

    /**
     * Caso seja verdadeito, não será criada transação
     * 
     * @return the none
     */
    public boolean isNone() {
        return this.equals(NONE);
    }

    /**
     * @param controller um {@link TransactionalController}
     */
    public void startTransaction(TransactionalController controller) {
        controller.startTransaction();
    }

    /**
     * @param controller um {@link TransactionalController}
     */
    public void rollbackTransaction(TransactionalController controller) {
        controller.rollback();
    }

    /**
     * @param controller um {@link TransactionalController}
     */
    public void commitTransaction(TransactionalController controller) {
        controller.commit();
    }

}
